/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package net.worlds.lua;

import org.jbox2d.common.Vec2D;
import se.krka.kahlua.vm.JavaFunction;
import se.krka.kahlua.vm.LuaCallFrame;


public class Vec2DFunctions {
    public static class Vec2DTostring implements JavaFunction
    {
        public int call(LuaCallFrame callFrame, int nArguments) {
            callFrame.push(callFrame.get(0).toString());
            return 1;
        }

    }
    public static class Vec2DEq implements JavaFunction
    {
        public int call(LuaCallFrame callFrame, int nArguments) {
            final Vec2D obj1 = (Vec2D) callFrame.get(0);
            final Vec2D obj2 = (Vec2D) callFrame.get(1);
            callFrame.push(obj1.equals(obj2));
            return 1;
        }
    }
    public static class Vec2DAdd implements JavaFunction
    {
        public int call(LuaCallFrame callFrame, int nArguments) {
            Object obj1 = callFrame.get(0);
            Object obj2 = callFrame.get(1);
            if(!(obj1 instanceof Vec2D && obj2 instanceof Vec2D))
                throw new RuntimeException("Cannot add "+obj1+" and "+obj2);
            callFrame.push(((Vec2D)obj1).add((Vec2D)obj2));
            return 1;
        }
    }
    public static class Vec2DSub implements JavaFunction
    {
        public int call(LuaCallFrame callFrame, int nArguments) {
            Object obj1 = callFrame.get(0);
            Object obj2 = callFrame.get(1);
            if(!(obj1 instanceof Vec2D && obj2 instanceof Vec2D))
                throw new RuntimeException("Cannot subtract "+obj1+" and "+obj2);
            callFrame.push(((Vec2D)obj1).sub((Vec2D)obj2));
            return 1;
        }
    }
    public static class Vec2DMul implements JavaFunction
    {
        public int call(LuaCallFrame callFrame, int nArguments) {
            Object obj1 = callFrame.get(0);
            Object obj2 = callFrame.get(1);
            if(!(obj1 instanceof Vec2D && obj2 instanceof Vec2D))
                throw new RuntimeException("Cannot multiply "+obj1+" and "+obj2);
            callFrame.push(((Vec2D)obj1).mul((Vec2D)obj2));
            return 1;
        }
    }
    public static class Vec2DDiv implements JavaFunction
    {
        public int call(LuaCallFrame callFrame, int nArguments) {
            Object obj1 = callFrame.get(0);
            Object obj2 = callFrame.get(1);
            if(!(obj1 instanceof Vec2D && obj2 instanceof Vec2D))
                throw new RuntimeException("Cannot divide "+obj1+" and "+obj2);
            callFrame.push(((Vec2D)obj1).div((Vec2D)obj2));
            return 1;
        }
    }
    public static class Vec2DIndex implements JavaFunction
    {
        public int call(LuaCallFrame callFrame, int nArguments) {
            final Vec2D vec = (Vec2D) callFrame.get(0);
            String k = callFrame.get(1).toString();
            if(k.equals("x"))
                callFrame.push(vec.x);
            else if(k.equals("y"))
                callFrame.push(vec.y);
            else if(k.equals("length"))
                callFrame.push(vec.length());
            else if(k.equals("normalized"))
                callFrame.push(vec.normalized());
            else if(k.equals("add"))
            {
                callFrame.push(new JavaFunction()
                {
                    public int call(LuaCallFrame callFrame, int nArguments) {
                        if(!(callFrame.get(1) instanceof Vec2D))
                            throw new RuntimeException("Argument to add() must be a Vec2D");
                        callFrame.push(vec.add((Vec2D)callFrame.get(1)));
                        return 1;
                    }
                });
            }
            else if(k.equals("sub"))
            {
                callFrame.push(new JavaFunction()
                {
                    public int call(LuaCallFrame callFrame, int nArguments) {
                        if(!(callFrame.get(1) instanceof Vec2D))
                            throw new RuntimeException("Argument to add() must be a Vec2D");
                        callFrame.push(vec.sub((Vec2D)callFrame.get(1)));
                        return 1;
                    }
                });
            }
            else if(k.equals("mul"))
            {
                callFrame.push(new JavaFunction()
                {
                    public int call(LuaCallFrame callFrame, int nArguments) {
                        if(callFrame.get(1) instanceof Vec2D)
                        {

                            callFrame.push(vec.mul((Vec2D)callFrame.get(1)));
                        }
                        else if(callFrame.get(1) instanceof Double)
                        {
                            callFrame.push(vec.mul((float)(double)(Double)callFrame.get(1)));
                        }
                        else
                            throw new RuntimeException("Argument to mul() must be a Vec2D or a number");
                        return 1;
                    }
                });
            }
            else if(k.equals("div"))
            {
                callFrame.push(new JavaFunction()
                {
                    public int call(LuaCallFrame callFrame, int nArguments) {
                        if(callFrame.get(1) instanceof Vec2D)
                        {

                            callFrame.push(vec.div((Vec2D)callFrame.get(1)));
                        }
                        else if(callFrame.get(1) instanceof Double)
                        {
                            callFrame.push(vec.div((float)(double)(Double)callFrame.get(1)));
                        }
                        else
                            throw new RuntimeException("Argument to div() must be a Vec2D or a number");
                        return 1;
                    }
                });
            }
            else
                throw new RuntimeException(k+" is not a member of Vec2D");
            return 1;
        }
    }
}
